home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / tuner / canvas / tuner.c next >
Encoding:
C/C++ Source or Header  |  1993-06-06  |  41.2 KB  |  1,447 lines

  1. /*
  2. %    TUNER . C
  3. %
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5.  
  6. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  7. Permission is granted to reproduce this software for non-commercial
  8. purposes provided that this notice is left intact.
  9.  
  10. It is acknowledged that the U.S. Government has rights to this software
  11. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  12. and the University of California.
  13.  
  14. This software is provided as a professional and academic contribution
  15. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  16. with no warranties of any kind whatsoever, no support, no promise of
  17. updates, or printed documentation. By using this software, you
  18. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  19. University of California shall have no liability with respect to the
  20. infringement of other copyrights by any part of this software.
  21.  
  22. For further information about this notice, contact William Johnston,
  23. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  24. (wejohnston@lbl.gov)
  25.  
  26. For further information about this software, contact:
  27.     Jin Guojun
  28.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  29.     g_jin@lbl.gov
  30.  
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. %
  33. %    The ELASTIC TUNER main routine Tuner(), editor routines.
  34. %
  35. %    There are 2 places (case fButton & Button3) re-using histogram().
  36. %    Of course, if there are more memory in system, this time can be saved.
  37. %    Two versions are set up here:
  38. %        direct color mapping and quantizing mode.
  39. %
  40. % compile:    -DDIRECT will generate fast version, but will not share
  41. %        color map with other images runing with it. And this fast
  42. %        version is mainly used for image viewing, not editing.
  43. %
  44. % Author:    Jin Guojun - Lawrence Berkeley Laboratory    4/1/91
  45. */
  46.  
  47. #include "tuner.h"
  48. #include "info_any.c"
  49.  
  50. #define    Dpy1    Monitor[1].dpy
  51. #define    Put_Image(img)    XPutImage(img->dpy,    \
  52.         img->refresh_pixmap ? img->refresh_pixmap : img->win,    \
  53.         img->gc, img->image, 0, 0, 0, 0, img->width, img->height);
  54.  
  55. bool    clickon, moved,    /* for pointer motion    */
  56.     newmap, cquire, cca, verbose, quant;
  57. int    ncolors=NCOLOR, BackGD, OsameI, num_images,
  58.     x_regions=2, y_regions=2,
  59.     fontWidth, fontHeight;    /* public font size */
  60. LKT    *lkt;
  61. MType    fsize;
  62. Image    **pic;
  63. Cursor    arrow;
  64. EditorSpace    I_ED;
  65. Image    cmn_hd;
  66. static    char    lbuf[128], *EmptySheet="empty frame";
  67.  
  68.  
  69. static    int    MBUTTON_ACTION[3][3]={
  70.     CONTROL_EVENT,    MAGNIFY_EVENT,    MENU1,
  71.     HISTO_EVENT,    MAGNIFY_SHIFT,    MENU2,
  72.     MOVIE_EVENT,    UNMAGNIFY,    MENU3
  73.     };
  74.  
  75. GetImageBufNSize(img)
  76. register Image    *img;
  77. {
  78. register int    size = img->width * img->height;
  79.     img->cnvt = img->data + (img->color_dpy ? 0 : img->fn * size);
  80. return    size;
  81. }
  82.  
  83. #ifdef    C_TUNER
  84.  
  85. #define    ImageBackup(img)    if (img->refresh_pixmap)    \
  86.     XCopyArea(img->dpy, img->refresh_pixmap, img->win, img->gc,    \
  87.         0, 0, img->width, img->height, 0, 0);
  88.  
  89. Tuner(imgp, max_images, active)
  90. Image    **imgp;
  91. bool    *active;
  92. {
  93. register MType    i;
  94. Image    *imginfo, *img;
  95. int    sb;
  96. XEvent        event;    /* p16 Xlib.h    */
  97. XExposeEvent    *expose;/* p11 Xlib.h    */
  98. XCrossingEvent    *xcrossing;
  99. expose = (XExposeEvent *) &event;
  100. xcrossing = (XCrossingEvent *) &event;
  101.  
  102. for (i=0; i<num_images; i++)
  103.     imgp[i]->event = &event;
  104. for (i=0; i<num_images; i++)
  105.     if (imgp[i]->active)    break;
  106. if (i >= num_images)
  107.     i = 0;
  108. imginfo = img = imgp[i];
  109. PanelMessage(FButton, img->name, 0, 0, 0);
  110. if (img->marray)
  111.     memcpy(&img->mmm, img->marray, sizeof(img->mmm));
  112. img->cnvt = img->data;
  113.  
  114. if (*active<0)    XMapWindow(Epanel->dpy, Epanel->win);
  115.  
  116. #else    Gray_Scale_tuner
  117.  
  118.  
  119. main(argc, argv)
  120. int    argc;
  121. char    **argv;
  122. {
  123. register int    i;
  124. int    VCTolerance=0, max_images=12, ela_scale=6, nf, xy_ext=0;
  125. float    thdscale=0.005000001;
  126. char    **fl;
  127.  
  128. format_init(&cmn_hd, IMAGE_INIT_TYPE, HIPS, HIPS, *argv, "S20-1");
  129.  
  130. if ((nf=parse_argus(&fl, argc, argv, arg_list,
  131. #ifdef    DIRECT
  132.     &VCTolerance,
  133. #else
  134.     &ncolors,
  135. #endif
  136.     &cca, &cquire,
  137.     &DEBUGANY, &DEBUGANY,
  138.     &display_name, &display_name,
  139.     &thdscale, &ela_scale,
  140.     &max_images,
  141.     &newmap, &precision,
  142.     &start_fast, &verbose,
  143.     &xy_ext, &x_regions, /*&y_regions,*/
  144.     &x_regions, &y_regions)) < 0)    exit(nf);
  145.  
  146. if (!xy_ext)    y_regions = x_regions;
  147. if (!VCTolerance)
  148.     VCTolerance = (ncolors>>ToleranceFactor)+16;
  149. if (precision<128)    /* small value may get more close color */
  150.     precision = 256;    /* but easy to failure */
  151.  
  152.     /* Open the display & set defaults */
  153. if ((Dpy1 = XOpenDisplay(display_name)) == NULL)
  154.     syserr("Can't open display '%s'", XDisplayName(display_name));
  155. if (!display_name)    display_name = XDisplayName(display_name);
  156. i = strlen(display_name);
  157. msg("display = %s\n", display_name);
  158.  
  159. if (display_name[i-1] != '0') {    /* number 0 {48H in ASCII} */
  160. char    str[64];
  161.     strcpy(str, display_name);
  162.     str[i-1] = '0';
  163.     if ((Dpy = XOpenDisplay(str)) == NULL)
  164.         syserr("Can't open display '%s'", str);
  165.     msg("display = %s\n", str);
  166. }
  167. else    Dpy = Dpy1;
  168. Set_Monitor(NULL, Dpy, Dpy1, NULL);
  169.  
  170. if (XDisplayPlanes(Dpy1, Monitor[1].screen) == 1)
  171.     mesg("control panel is on a monochrome screen\n");
  172.  
  173. dgt = (int*) zalloc(MaxColors, sizeof(*dgt), "dgt");
  174. if (Monitor[0].dpy_depth < 24)
  175.     GetVctEntry(Dpy, Screen, Monitor[0].cmap,
  176.         start_fast<2 && Monitor[1].dpy_depth>1 ||
  177.         Dpy==Dpy1 && Monitor[1].dpy_depth==1);
  178. else    VCTEntry = 1;
  179.  
  180. #ifdef    DIRECT
  181. if (VCTEntry<1 || ncolors+VCTEntry-MaxColors > VCTolerance)
  182.     newmap--;
  183. CreateCLT(graylevel, ncolors, DoAll, 0, False, &histinfo);
  184. Monitor[0].cmap = SetColormap(&Monitor[0], graylevel, ncolors, &newmap,
  185.     VCTEntry);
  186. #else
  187. if (VCTEntry < 1)    newmap--;
  188. else if (ncolors+VCTEntry-MaxColors > VCTolerance)
  189.     ncolors >>= 1;
  190. CreateCLT(graylevel, ncolors, DoAll, 0, True, &histinfo);
  191. Monitor[0].cmap = SetColormap(&Monitor[0], graylevel, &ncolors, &newmap, 0);
  192. #endif
  193. if (Dpy == Dpy1)
  194.     Monitor[1].cmap = Monitor[0].cmap;
  195. if (max_images<1 || max_images>256)
  196.     max_images = 64;
  197.  
  198. cmn_hd.dpy = Dpy;
  199. cmn_hd.dpy_depth = Monitor[0].dpy_depth;
  200. CreateTuner(&cmn_hd, ela_scale, darkGray, True);
  201.  
  202. pic = (Image**) zalloc(max_images, sizeof(**pic), "pic");
  203.  
  204.     /* if stdin is ready, load image. */
  205. i = True;
  206. io_test(fileno(stdin), i=iset);
  207. if (i)    LoadImage(stdin, pic, fname);
  208. else  while (i < nf)    {
  209.     if (!(freopen(fname=fl[i], "rb", stdin)) )
  210.         syserr("input %s", fl[i]);
  211.     LoadImage(stdin, pic+i++, fname);
  212. }
  213. Tuner(pic, max_images);    /* analyse images */
  214. }    /* End of Main    */
  215.  
  216.  
  217. Tuner(imgp, max_images)
  218. Image    **imgp;
  219. {
  220. Image    *img = imgp[0],    /* only set by load, map, enter.
  221.             So, it always represents the current image */
  222.     *imginfo=NULL;    /* temp image pointer, parameter window    */
  223. int    sb;
  224. XEvent        event;    /* p16 Xlib.h    */
  225. XExposeEvent    *expose;/* p11 Xlib.h    */
  226. XCrossingEvent    *xcrossing;
  227. register MType    i=0;
  228.  
  229. while (img=imgp[i])    {
  230.     img->cnvt = img->data;    i++;
  231.     img->event = &event;
  232. }
  233. if (num_images = i)
  234.     (img=imgp[--i])->active = True;
  235. XSelectInput(histinfo.his->dpy, histinfo.his->win, I_Mask);
  236. expose = (XExposeEvent *) & event;
  237. xcrossing = (XCrossingEvent *) & event;
  238.  
  239. I_ED.copy = (Image*) nzalloc(sizeof(*I_ED.copy), 1, "I_copy");
  240.  
  241. #endif     C_TUNER
  242.  
  243.  
  244. /*    public tuner()    */
  245.  
  246. #ifndef    HISTO_BACKGROUND
  247. #define    HISTO_BACKGROUND    lightGray
  248. #endif
  249.  
  250. while (True) {    /* the loop to maintain the images.    PUBLIC entry */
  251. #ifdef    _DEBUG_
  252. #include <time.h>
  253. time_t    t0, t1;
  254. #endif
  255.  
  256. int    mevent, y0, new_colors=ncolors, ps=1;
  257. Window    wp;    /* long, defined in X.h */
  258. KeySym    keysym;
  259. XComposeStatus    stat;
  260.     if (event.type != MotionNotify) {
  261.         sprintf(lbuf,
  262.         "(q)uit   {%d}%-8d BUTTON => [1]Ctrl   [2]Hist   [3]Movie",
  263.         histinfo.scale, img?img->mmm.maxcnt:0);
  264.         DispInfo(Epanel, 0, lbuf, white1);
  265.     }
  266.     if (Dpy == Dpy1)
  267.         XNextEvent(Dpy, &event);/* waiting for event */
  268.     else    {
  269.         i = 0;
  270.         while (!XEventsQueued(Dpy, QueuedAfterFlush) &&
  271.             !(i=XEventsQueued(Dpy1, QueuedAfterFlush)));
  272.         if (i)    XNextEvent(Dpy1, &event);
  273.         else    XNextEvent(Dpy, &event);
  274.     }
  275.  
  276.     wp = event.xany.window;
  277.     switch ((int) event.type) {
  278.     case Expose:
  279.         if ((i=WhichImage(wp, imgp, num_images))>=0)
  280.             imginfo = imgp[i];
  281.         Exposure_handler(expose, imginfo);
  282.     XFlush(Dpy);
  283.     break;
  284.  
  285.     case ButtonPress:
  286.         i = event.xbutton.button;
  287.         mevent = event.xbutton.state & (ShiftMask | ControlMask);
  288.         if (mevent>2)    mevent = 2;
  289.         mevent = MBUTTON_ACTION[i-Button1][mevent];
  290.         if (OnButton(FButton, &event.xbutton) > 0 &&
  291.         (i=FileAccess(imgp, max_images, num_images))) {
  292.             if (img)    img->active = False;
  293.             if (i == EOF)    {    /* SUCCESSful LOADing    */
  294.                 img = imgp[num_images];
  295.                 img->event = &event;
  296.                 num_images++;
  297.             }
  298.             else    img = imgp[i];
  299.             img->active = True;
  300. #    ifdef    DIRECT
  301.             frmchange++;
  302. #    endif
  303.             img->cnvt = img->data;
  304.             break;
  305.         }
  306.         else if (mevent==MENU2) {
  307.         switch (i=PopingMenu(paramenu, numpara, NULL)) {
  308.         case MENU2_FITSType:    {
  309. #ifdef    FITS_IMAGE
  310.         extern    int    FTy;
  311.             sprintf(lbuf, "[%c] Unix Vax Pc T->unix_vax", FTy);
  312.             Get_Note_Input(lbuf, sizeof(lbuf), 7, "TYPE ", Yellow, 0);
  313.             FTy = lbuf[0];
  314.             if (FTy != 'u' && FTy != 'v' && FTy != 'p' && FTy != 't')
  315.                 FTy = 'u';
  316. #endif
  317.         }    break;
  318.         case MENU2_ETAScale:
  319.             if (!img)    break;
  320.             sprintf(lbuf, "\n\nlevel = %d (Max : 65)", img->scale);
  321.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "scale ", Yellow, Yes);
  322.             img->scale = i = atoi(lbuf);
  323.             ChangeSliderScale(ESlider, i, slider==ESlider);
  324.             break;
  325.         case MENU2_ITPRange:
  326.             sprintf(lbuf, "level = %d, Max level = 8", x_regions);
  327.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "level ", Green, 0);
  328.             i = atoi(lbuf);
  329.             if (i<2 || i>MAX_ITP_LEVEL)    i = 2;
  330.             x_regions = y_regions = i;
  331.             break;
  332.         case MENU2_RGBScale:
  333.             sprintf(lbuf, "R-G-B = %d %d %d",
  334.                 RED_to_GRAY, GREEN_to_GRAY, BLUE_to_GRAY);
  335.             Get_Note_Input(lbuf, sizeof(lbuf), 0, "R.G.B factor ", Green, 0);
  336.             sscanf(lbuf, "%d %d %d",
  337.                 &RED_to_GRAY, &GREEN_to_GRAY, &BLUE_to_GRAY);
  338.             break;
  339.         case MENU2_BackGD:
  340.             sprintf(lbuf, "Background = %d", BackGD);
  341.             Get_Note_Input(lbuf, sizeof(lbuf), 0, "new back ground ", Green, 0);
  342.             BackGD = atoi(lbuf);
  343.             break;
  344.         default:    XBell(Epanel->dpy, 10);
  345.         }
  346.         HidingPanel(NoteWin);
  347.         break;
  348.         }
  349.         else if (mevent==MENU3)    {
  350.         char    errbuf[128];
  351.         switch(i = PopingMenu(filemenu, numcomd, NULL))    {
  352.         case MENU3_BLKFrm:    {
  353.             int    w, h;
  354.             strcpy(lbuf, "new frame size:\n width height");
  355.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, Green, 0);
  356.             sscanf(lbuf, "%d %d", &w, &h);
  357.             if (w < 64 || h < 64)
  358.                 WaitOk(AbortButt, "size to small", 0);
  359.             else {
  360.             register int    chan = cmn_hd.color_dpy ? 3 : 1;
  361.             register byte    *clean;
  362.                 if (num_images >= max_images)
  363.                     break;
  364. #    ifdef    C_TUNER
  365.                 if (chan==3) {
  366.                 int    icn_f;
  367.                     img = imgp[num_images] = (Image*)zalloc(1,
  368.                         sizeof(image_information), EmptySheet);
  369.                     init_img_info(img, Dpy, RLE, cmn_hd.color_dpy);
  370.                     img->active = img->pixmap_failed = 1;
  371.                     init_img_flag(img);
  372.                     img->width = w,    img->height = h;
  373.                     img->channels = img->dpy_channels = chan;
  374.                     img->name = EmptySheet;
  375.                     find_appropriate_visual(img);/* may copy from parent */
  376.                     BuildColorImage(img, NULL, NULL, &icn_f);
  377.                 } else
  378. #    endif
  379.                 {       imgp[num_images] = NULL;
  380.                     BuildImage(imgp+num_images, "tmp", w, h,
  381.                         1, NULL, chan==1 ? HIPS : RLE, True);
  382.                     img = imgp[num_images];
  383.                     img->colormap = Monitor[0].cmap;
  384.                     img->channels = img->dpy_channels = chan;
  385.                 }
  386.                 num_images++;
  387.                 img->color_form = chan==3 ? CFM_ILL : CFM_SCF;
  388.                 img->in_type = img->o_type = RLE;
  389.                 SetImageEvent(img, &event);
  390.                 img->data = clean = nzalloc(w*h, chan, "blk-data");
  391.                 if (chan > 1)
  392.                     img->scan_data = nzalloc(w*h, chan, "blk-scan");
  393.                 for (chan*=w*h; chan--;)
  394.                     clean[chan] = -1;
  395.             }
  396.         }    break;
  397.         case MENU3_CDIR:
  398.             sprintf(lbuf, "%s\nChange directory to",
  399.                 getcwd(NULL, 256));
  400.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, Green, 0);
  401.             if (chdir(lbuf)) {
  402.                 sprintf(errbuf, "wrong directory:\n  %s", lbuf);
  403.                 WaitOk(NULL, errbuf, 0);
  404.             }
  405.             break;
  406. #    ifdef    C_TUNER
  407.         case MENU3_MAP123:
  408.             OsameI = YesOrNo("Map 1 to 3 channels for input ?", 0);
  409.             break;
  410.         case MENU3_LDFrm:
  411.             sprintf(lbuf, "frame = %d", img->fn);
  412.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, 0, 0);
  413.             img->fn = atoi(lbuf);
  414.             break;
  415. #    endif
  416.         case MENU3_OType:
  417.             sprintf(lbuf, "OUTPUT TYPE : %s\nHIPS, RAS, RLE",
  418.                 ITypeName[img->o_type]);
  419.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, 0, 0);
  420.             if ((i=available_type(lbuf)) > 0)
  421.                 img->o_type = i;
  422.             break;
  423.         case MENU3_QUIT:    goto    MEXIT;
  424.         }
  425.         HidingPanel(NoteWin);
  426.         break;
  427.         }
  428.         else if (!img)
  429.         break;
  430.  
  431.         if ((wp==img->win || wp==histinfo.his->win) &&
  432.         (mevent==CONTROL_EVENT || mevent==MOVIE_EVENT))    {
  433.         if (wp==img->win) {
  434.             XDefineCursor(img->dpy, wp, 0);
  435.             imginfo = img;
  436.         }
  437.         else{    imginfo = histinfo.his;
  438.             imginfo->mmm = img->mmm;
  439.         }
  440.         y0 = SetParameterWin(imginfo, &event, fontHeight, i==Button3);
  441.         }
  442.         switch (mevent) {
  443.         case CONTROL_EVENT:    /* on Botton1 */
  444.         if (i=Button1_On(&event.xbutton, &sb))
  445.         switch (i)    {
  446.             case OnETASlider:
  447.             clickon=ELALINFO;    break;
  448.             case OnClipSlider:
  449.             clickon=CLIPINFO;    break;
  450.             case OnQuanSlider:
  451.             clickon=QUANINFO;    break;
  452.             case OnZcntButton:
  453.             cntz = ButtonState(ZButton);    break;
  454. #    ifndef    DIRECT
  455.             case OnQuanButton:
  456.             quant = ButtonState(QButton);
  457.             if (!quant)    {
  458.                 moved = new_colors = ncolors;
  459.                 CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  460.                 SetColormap(&Monitor[0], graylevel, &new_colors, &newmap, !quant);
  461.             }
  462. #    endif
  463.             break;
  464.             case OnFrameButton:
  465. #ifdef    C_TUNER
  466.             img->fn = ButtonState(fButton);
  467.             i = img->fn % 3;
  468.             img->mmm.min = img->marray[img->fn%img->channels].min;
  469.             img->mmm.max = img->marray[img->fn%img->channels].max;
  470.             img->curve = ButtonState(EButton) = cer[i].curve;
  471.             if (img->curve != ETALinear)
  472.                 SetSBarPos(ESlider, img->curve ?
  473.                 cer[i].bgrd : cer[i].fgrd, 1);
  474.             img->linearlow = cer[i].lower;
  475.             img->linearup = cer[i].upper;
  476.             ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  477.             PressButtonState(heqButt) = RESETSTATE;
  478.             DrawPressButton(heqButt);
  479. #else
  480.             if (img->frames>1) switch(ButtonState(fButton))    {
  481.             case NumFRAME:
  482.                 sprintf(lbuf, "Input frame# <= %d", img->frames);
  483.                 i = (strlen(lbuf)+2) * Epanel->font_w;
  484.                 DispInfo(Epanel, 0, lbuf, white1);
  485.                 lbuf[0] = 0;    /* clean buf */
  486.                 TextLine(fButton, lbuf, sizeof(lbuf), i,
  487.                     Exposure_handler, imgp, num_images);
  488.                 i = atoi(lbuf);
  489.                 if (i>0 && i<=img->frames)    img->fn = i-1;
  490.                 break;
  491.             case PrevFRAME:    if (img->fn)    img->fn--;
  492.                 break;
  493.             case NextFRAME:    if (img->fn<img->frames-1)
  494.                         img->fn++;
  495.             }
  496.             ButtonState(fButton)=RESETSTATE;
  497.             sprintf(lbuf, fb_format, img->fn+1, img->frames);
  498.             if (moved=strcmp(lbuf, fButton->bname[PosFRAME])) {
  499.                 fsize = GetImageBufNSize(img);
  500.                 i = histogram(img->cnvt, fsize, histinfo.histp, 0);
  501.                 img->mmm.min = img->marray[img->fn].min;
  502.                 img->mmm.max = img->marray[img->fn].max;
  503.                 if (!img->setscale)
  504.                     img->mmm.maxcnt = i,
  505.                     ResetORange(img);
  506.                 strcpy(fButton->bname[PosFRAME], lbuf);
  507. #    ifdef    DIRECT
  508.                 frmchange++;
  509. #    endif
  510.             }
  511.             DrawButton(fButton);
  512. #    endif
  513.             break;
  514.             case OnDataButton:    /* update image->data */
  515.             Update_ImageData(img, img->cnvt, lbuf);
  516.             case OnInterpolate:
  517.             cer[0].intp = i==OnInterpolate;
  518.             if (cer[0].intp && img->color_form == CFM_SCF)    {
  519.                 ButtonState(Interpolate) = RESETSTATE;
  520.                 break;
  521.             }
  522.             Find_min_max(img, histinfo.histp, img->cnvt, Yes, True);
  523.             case OnETAButton:
  524.             img->curve = ButtonState(EButton);
  525. #    ifdef    C_TUNER
  526.             i = img->fn % 3;
  527.             cer[i].curve = img->curve;
  528.             img->bgrd = cer[i].bgrd;
  529.             img->fgrd = cer[i].fgrd;
  530.             img->linearlow = cer[i].lower;
  531.             img->linearup  = cer[i].upper;
  532. #    endif
  533.             ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  534.             moved++;
  535.             break;
  536.  
  537.             case OnHistButton:
  538.             Histo_Setting(img, lbuf);
  539.             break;
  540.             case OnResetButton:
  541.             {
  542.             moved++;
  543.             ResetORange(img);
  544.             }    break;
  545.             case OnRefresh:
  546.             moved++;
  547.             img->curve &= ~ETAHistoEq;
  548.             break;
  549.             case OnHEQButton:
  550.             moved = img->curve |= ETAHistoEq;
  551.             break;
  552.             default:    /* a lazy job ! should do something better */
  553.             if ((i=WhichImage(wp, imgp, num_images))>=0 &&
  554.                 img->parts && (sb=OnScrollBar(img->parts,
  555.                 &event.xbutton)))
  556.                 clickon = MOVESCROLLBAR;
  557.             else if (wp != Epanel->win)    {
  558. #    ifdef    C_TUNER
  559.                 if (wp != histinfo.his->win)
  560.                 ColorImageInfo(img, !y0);
  561.                 else
  562. #    endif
  563.                 ParameterWin(imginfo, &histinfo,
  564.                     event.xbutton.x, event.xbutton.y,
  565.                     y0, wp==histinfo.his->win),
  566.                 clickon = IMAGEINFO;
  567.             }
  568.         } break;    /* end of Button1 */
  569.         case HISTO_EVENT:    /* on Button2    */
  570.         if (img)    Map_HistoWin(img);
  571.         break;
  572.  
  573.         case MOVIE_EVENT:    /* on Button3    */
  574.         XBell(Dpy, 0);
  575. #    ifdef    _DEBUG_
  576.         time(&t0);
  577. #    endif
  578. #    ifndef    C_TUNER
  579.         if(OnButton(fButton, &event.xbutton) > 0 &&
  580.         event.xbutton.window == Epanel->win)    {
  581.         char    val[8];
  582.         DispInfo(Epanel, 0, "s => stop", Yellow);
  583.         if (img->curve & ETAHistoEq)    strcpy(lbuf, "Histo Equalization");
  584.         else if(img->curve<ETALinear)    strcpy(lbuf, "Elastic");
  585.         else    strcpy(lbuf, "Linear");
  586.         DispInfo(Epanel, 100, lbuf, Yellow);
  587.         while(1){
  588.             if (ButtonState(fButton) == PrevFRAME)
  589.                 if (img->fn)    img->fn--;
  590.                 else    break;
  591.             else if(img->fn<img->frames-1)    img->fn++;
  592.                 else    break;
  593.             if (XCheckMaskEvent(Dpy, KeyPressMask, &event)){
  594.                 XLookupString(&event, lbuf, sizeof(lbuf),
  595.                     &keysym, &stat);
  596.                 if (lbuf[0] == 's')    break;
  597.             }
  598.             GetImageBufNSize(img);
  599.             img->mmm.min = img->marray[img->fn].min;
  600.             img->mmm.max = img->marray[img->fn].max;
  601.             if (!img->setscale)
  602.                 img->mmm.maxcnt = img->marray[img->fn].maxcnt,
  603.                 ResetORange(img);
  604.             new_curve(lkt, &histinfo, &img->mmm, img->curve, 0,
  605.                 img, fsize);
  606. #    ifdef    DIRECT
  607.             frmchange++;
  608.             MapColor(img, img->cnvt, fsize,
  609.                 graylevel, MAX(VCTEntry, img->mmm.min));
  610. #    else
  611.             MapColor(img, img->cnvt, fsize);
  612. #    endif
  613.             if (histinfo.map){
  614.                 histogram(img->cnvt, fsize, histinfo.histp, 0);
  615.                 HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  616.                 sprintf(lbuf, "%d", img->mmm.maxcnt);
  617.                 DispInfo(Epanel, 240, lbuf, Green);
  618.                 SetShowFramePos(img, fButton, 0);
  619.             }
  620.         }
  621.         SetShowFramePos(img, fButton, True);
  622.         if (img->sub_img)
  623.             DrawCrop(img, 0, 1);
  624. #    ifdef    _DEBUG_
  625.         time(&t1);
  626.         message("time = %d\n", t1-t0);
  627. #    endif
  628.         }
  629.         else
  630. #    endif
  631.         if (event.xany.window == img->win)
  632.         TrackSubWin(img, &histinfo, event.xbutton.x, event.xbutton.y,
  633.             DrawsRect, CropButton, y0);
  634.         else if (event.xany.window == histinfo.his->win){
  635.         DrawVMark(histinfo.his, event.xmotion.x, histinfo.his->sub_img);
  636.         histinfo.his->sub_img = clickon = HMARKPOS;
  637.         }break;    /* end of MOVIE_EVENT    */
  638.         case MENU1:    /* case ACTION_OBJECT:    */
  639.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0 &&
  640.             (i=on_superimpose_elem(imginfo=imgp[i],
  641.                 event.xbutton.x, event.xbutton.y)))
  642.             superimpose_handle(imginfo, i,
  643.                 event.xbutton.x, event.xbutton.y);
  644.         else switch (i=PopingMenu(ctrlmenu, 2, Exposure_handler,
  645.                 imgp, num_images))    {
  646.         case MENU1_INFO:
  647.             Toggle_Info(Help_message_array1);
  648.             break;
  649.         case MENU1_CUT:    /* img == imginfo */
  650.             img->update |= img->sub_img;
  651.         case MENU1_COPY:
  652.             if (img->sub_img)
  653.                 CopyOrCutSubImage(img, i==MENU1_CUT);
  654.             else    XBell(img->dpy, 0);
  655.             break;
  656.         case MENU1_CROP:
  657.             sprintf(lbuf, "size: %dH x %dW\ncrop => X0 Y0 height width",
  658.                 img->height, img->width);
  659.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "sub-image ", Yellow, 0);
  660.             sscanf(lbuf, "%d %d %d %d", &img->sub_img_x,
  661.                 &img->sub_img_y,&img->sub_img_h,&img->sub_img_w);
  662.             bound_check(img->sub_img_h, img->sub_img_y, img->height);
  663.             bound_check(img->sub_img_w, img->sub_img_x, img->width);
  664.             img->sub_img = (img->height>4 && img->width>4);
  665.             break;
  666.         case MENU1_DRAW:
  667.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  668.                 lbuf, sizeof(lbuf), &event)) >= 0)
  669.                 DrawInImage(imginfo=imgp[i], &y0, PaintMesg, lbuf);
  670.             break;
  671.         case MENU1_PASTE:
  672.             if (!I_ED.fill)    break;
  673.             DisplayMessage(NoteWin, PasteMesg, 0, 0);
  674.             XMaskEvent(Dpy, ButtonPressMask, &event);
  675.             if ((i=WhichImage(event.xany.window, imgp, num_images))>=0)
  676.             PasteImage(imginfo=imgp[i], &y0);
  677.             break;
  678.         case MENU1_PAINT:
  679.             sprintf(lbuf, "brush radius = %d", ps);
  680.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "radius ", Green, 0);
  681.             sscanf(lbuf, "%d", &ps);
  682.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  683.                 lbuf, sizeof(lbuf), &event)) >= 0)
  684.                 PaintImage(imginfo=imgp[i], &y0, ps,
  685.                     fnt_r, fnt_g, fnt_b);
  686.             break;
  687.         case MENU1_ANOT:
  688.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  689.                 lbuf, sizeof(lbuf), &event)) >= 0)
  690.                 Annotation(imginfo=imgp[i], &y0, &keysym, &stat);
  691.             break;
  692.         case MENU1_MEAN:
  693. #    ifdef    C_TUNER
  694.             if (img->dpy_channels > 1 && img->sub_img)    {
  695.             byte    *scan[3], *smap[3];
  696.             register int    fact = get_iconsize(img, 0),
  697.                 x = img->sub_img_x, y = img->sub_img_y,
  698.                 iw = img->width;
  699.                 CalcSubWinMean(img->data, img->data, iw,
  700.                 x, y, img->sub_img_w, img->sub_img_h);
  701.                 for (i=img->sub_img_h; i--;)    {
  702.                 scan[0] = ORIG_RLE_ROW(img, y + i) + x;
  703.                 scan[1] = scan[0] + iw;
  704.                 scan[2] = scan[1] + iw;
  705.                 smap[0] = SAVED_RLE_ROW(img, y + i) + x;
  706.                 smap[1] = smap[0] + iw;
  707.                 smap[2] = smap[1] + iw;
  708.                 Map_Scanline(img, scan, smap, x, y + i,
  709.                     img->sub_img_w, fact);
  710.                 }
  711.                 if (img->refresh_pixmap)
  712.                 XPutImage(img->dpy, img->refresh_pixmap,
  713.                     img->gc, img->image, x, y, x, y,
  714.                     img->sub_img_w, img->sub_img_h);
  715.                 handle_exposure(img, Draws, x, y,
  716.                 img->sub_img_w, img->sub_img_h,
  717.                 img->height, img->update=True);
  718.             }
  719. #    endif
  720.             break;
  721.         case MENU1_SNAP:{
  722.         extern    XColor    qcolor[MaxColors];
  723.         register XImage    *ip;
  724.             Window    win;
  725.             XWindowAttributes    wa;
  726.             register int    j = i = 256;
  727.             XMaskEvent(Dpy, ButtonPressMask, &event);
  728.             win = event.xany.window;
  729.             XGetWindowAttributes(Dpy, win, &wa);
  730.             ip  = XGetImage(Dpy, win, 0, 0, wa.width, wa.height, AllPlanes, ZPixmap);
  731.             img = imgp[num_images++] = zalloc(1, sizeof(*img), "snap");
  732.             init_img_info(img, Dpy, cmn_hd.color_dpy ? RLE : HIPS, cmn_hd.color_dpy);
  733.             img->width = wa.width;    img->height = wa.height;
  734.             img->colormap = wa.colormap;
  735.             img->dpy_channels = img->channels = 1;
  736.             img->color_form = cmn_hd.color_dpy ? CFM_SCF : CFM_SGF;
  737.             img->name = "snap window";
  738.             CreateWindow(img, Monitor, 0, I_Mask | KeyPressMask,
  739.                 0, IconWindowHint | IconPositionHint);
  740.             img->image = ip;
  741.             img->dpy_depth = Monitor[0].dpy_depth;
  742.             img->data = img->scan_data = img->img_buf = ip->data;
  743.             SetImageEvent(img, event);
  744.             XMapWindow(img->dpy, img->frame);
  745.             GetCloseColor(Dpy, wa.colormap, i, 0, 240, 240, 240);
  746.             img->cmaplen = i;
  747.             if (verify_buffer_size(reg_cmap, i * 3, sizeof(cmap_t),
  748.                 "snap_map")) {
  749.                 img->in_cmap = reg_cmap;
  750.                 reg_cmap[1] = reg_cmap[0] + i;
  751.                 reg_cmap[2] = reg_cmap[1] + i;
  752.             }
  753.             while (i--)    {
  754.                 reg_cmap[0][i] = qcolor[i].red >> 8;
  755.                 reg_cmap[1][i] = qcolor[i].green>>8;
  756.                 reg_cmap[2][i] = qcolor[i].blue>>8;
  757.             }
  758. #ifdef    C_TUNER
  759.             if (r_cmap)    free(r_cmap);
  760.             i = img->cmaplen;
  761.             rle_dflt_hdr.cmap = (rle_map*)(r_cmap = (sht_cmap_t*)
  762.                 zalloc(i*(img->ncmap=3), sizeof(*r_cmap), ""));
  763.             rle_dflt_hdr.cmaplen = 8;
  764.             while (i--)    {
  765.                 r_cmap[i] = qcolor[i].red;
  766.                 r_cmap[i + j] = qcolor[i].green;
  767.                 r_cmap[i + (j<<1)] = qcolor[i].blue;
  768.             }
  769. #else
  770.             img->data = nzalloc(i=img->width, img->height);
  771.             for (i *= img->height; i--;)
  772.                 img->data[i] = reg_cmap[0][ip->data[i]];
  773. #endif
  774.             Find_min_max(img, histinfo.histp, img->data, 1, True);
  775.             }
  776.         }    /* end switch(popmenu) */
  777.         HidingPanel(NoteWin);
  778.         break;
  779.         default:    msg("uninstalled event %d\n", mevent);
  780.     }    /* end of switch(mevent) */
  781.     break;    /* end of ButtonPress */
  782.  
  783.     case ButtonRelease:
  784.         if (moved)    {
  785.         switch(clickon)    {
  786.         case NULL:
  787.         case ELALINFO:    /* color() REG color=RGB%channels */
  788.             Fresh_ImageScreen(img, img->cnvt, &new_colors);
  789.             break;
  790.         case CLIPINFO:    topv = ReadSlider(CSlider, 2);
  791.                 top = ReadSlider(CSlider, 1);
  792.             break;
  793.         case QUANINFO:
  794.             if (!quant || ncolors > 64)    break;
  795. #    ifndef    DIRECT
  796.             new_colors = CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  797.             SetColormap(&Monitor[0], graylevel, &new_colors, &newmap, quant);
  798.             MapColor(img, img->cnvt, fsize);
  799. #    endif
  800.         case MOVESCROLLBAR:
  801. /*            XMoveWindow(img->dpy, img->win, -img->x0, -img->y0);
  802.             XMoveResizeWindow(img->dpy, img->parts->scrollbar.h_swin,
  803.                 img->x0+img->parts->scrollbar.rx[0],
  804.                 img->y0+img->parts->scrollbar.ry[0],
  805.                 img->parts->scrollbar.rl[0],
  806.                 img->parts->scrollbar.rw[0]);
  807.             XMoveResizeWindow(img->dpy, img->parts->scrollbar.v_swin,
  808.                 img->x0+img->parts->scrollbar.rx[1],
  809.                 img->y0+img->parts->scrollbar.ry[1],
  810.                 img->parts->scrollbar.rw[1],
  811.                 img->parts->scrollbar.rl[1]);
  812. */            Draw_ImageScrollBars(img);
  813.         }/* end switch */
  814.         moved = False;
  815.         PressButtonState(RstButt)=PressButtonState(rfsButt)=RESETSTATE;
  816.         if (PressButtonState(heqButt) && img->curve!=(ETAHistoEq|ETALinear)){
  817.             PressButtonState(heqButt) = RESETSTATE;
  818.             img->curve &= ~ETAHistoEq;
  819.         }
  820.         DrawPanel(); /* for reset pressbutton */
  821.         HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  822.         }
  823.         else if (img)    /* check for undo loading file and default */
  824.         switch (clickon)    {
  825.         case HMARKPOS:
  826.         case IMAGEINFO:
  827.             if (wp==img->win)    /* for image only */
  828.             XDefineCursor(img->dpy, wp, cursor);
  829.             if (wp != Epanel->win)
  830.             ClearParameterWin(imginfo, y0);
  831.         }
  832.         clickon = 0;
  833.     break;
  834.  
  835.     case KeyPress:    /* color() return *active = -1 */
  836.     {
  837.     char    *str, *XKeysymToString();
  838.     int    len;
  839.     bool    CTRL_Key;
  840.         len = XLookupString(&event, lbuf, sizeof(lbuf), &keysym, &stat);
  841.         lbuf[len] = 0;
  842.         str = XKeysymToString(keysym);    /* useful? */
  843.         CTRL_Key = event.xkey.state & ControlMask;
  844.         if (len == 1) {
  845.             if (*str == 'q' || *str == 'Q') {
  846. MEXIT:            if (!YesOrNo("Quit ?", 0)) {
  847.                 PressButtonState(YesButt) =
  848.                 PressButtonState(NoButt) = RESETSTATE;
  849.                 break;
  850.             }
  851.             if (num_images) {
  852.                 for (i=0; i<num_images; i++) {
  853.                 if (imgp[i]->update)
  854.                     SaveImage(imgp[i]);
  855. #ifdef    C_TUNER
  856.                 DestroyColorImage(imgp[i]);
  857. #else
  858.                 DestroyImage(imgp[i]);
  859. #endif
  860.                 }
  861.             }
  862.             if (newmap)
  863.                 XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  864.             XFreeGC(NoteWin->dpy, NoteWin->gc);
  865.             XDestroyWindow(NoteWin->dpy, NoteWin->win);
  866.             XFreeGC(ctrlmenu->dpy, ctrlmenu->gc);
  867.             XDestroyWindow(ctrlmenu->dpy, ctrlmenu->win);
  868.             XFreeGC(Epanel->dpy, Epanel->gc);
  869.             XDestroyWindow(Epanel->dpy, Epanel->win);
  870.             XCloseDisplay(Dpy);
  871.             if (Dpy1 && Dpy != Dpy1)
  872.                 XCloseDisplay(Dpy1);
  873.             exit(0);
  874.             }
  875.             if (tolower(*str) == 'c') {
  876. #    ifdef    C_TUNER
  877.             if (newmap)
  878.                 XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  879.             XUnmapWindow(Dpy, Epanel->win);
  880.             return    *active = -1;
  881. #    else
  882.             for (i=0; i<num_images; i++)
  883.                 if (imgp[i]->win == event.xany.window){
  884.                 if (imgp[i]->update)
  885.                     SaveImage(imgp[i]);
  886.                 DestroyImage(imgp[i]);
  887.                 while (++i < num_images)
  888.                     imgp[i-1] = imgp[i];
  889.                 imgp[--num_images] = NULL;
  890.                 if (num_images){
  891.                     img = imginfo = imgp[num_images-1];
  892.                     goto    ReSume;/* several lines down */
  893.                 }
  894.                 else    img = NULL;
  895.                 }/* end close image */
  896. #endif
  897.             }
  898.             else if(tolower(*str) == 'h')
  899.             Toggle_Info(Help_message_array1);
  900.         }
  901.     }break;
  902.  
  903.     case EnterNotify:
  904.         if ((i=WhichImage(event.xany.window, imgp, num_images)) >= 0){
  905.         imginfo = imgp[i];
  906.         if (imginfo == img)    break;
  907. ReSume0:    img->active = False;
  908.         img = imginfo;
  909. ReSume:        img->active = True;
  910.         fsize = GetImageBufNSize(img);
  911.         Panel_Image(img, lkt);
  912. #if    (defined DIRECT) & (!defined C_TUNER)
  913.         MapColor(img, img->cnvt, fsize, graylevel,
  914.             MAX(VCTEntry, img->marray[img->fn].min));
  915. #endif
  916.         }
  917.         if ((newmap || cca) && (xcrossing->mode != NotifyUngrab)){
  918.         XInstallColormap(Dpy, Monitor[0].cmap);
  919.         XInstallColormap(Dpy1, Monitor[1].cmap);
  920.         }
  921. #    ifdef    _DEBUG_
  922.         else    if (verbose)    mesg("enter notified\n");
  923. #    endif
  924.     break;
  925.  
  926.     case LeaveNotify:
  927.         if((newmap || cca) && (xcrossing->mode != NotifyGrab))
  928.         XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  929. #    ifdef    C_TUNER
  930.         if (!clickon)    {
  931.             *active = 1;
  932.             return    num_images;
  933.         }
  934. #    endif
  935.     break;
  936.  
  937.     case ColormapNotify:
  938. #ifdef    _DEBUG_
  939.     {    static    int    CN=0;
  940.         msg("color change happened %d\r", CN++);
  941.     }
  942. #endif
  943.     break;
  944.  
  945.     case MapNotify:
  946.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0){
  947.             imginfo = imgp[i];
  948.             if (event.xmap.window == imginfo->win){
  949.                 XUnmapWindow(imginfo->dpy, imginfo->icon);
  950. #ifndef    C_TUNER
  951.                 goto    ReSume0;
  952. #endif
  953.             }
  954.             else if (event.xmap.window == imginfo->icon)
  955.                 XUnmapWindow(imginfo->dpy, imginfo->frame);
  956.         }
  957.         while (XCheckMaskEvent(Dpy, StructureNotifyMask, &event));
  958.     break;
  959.  
  960.     case UnmapNotify:
  961.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0){
  962.             imginfo = imgp[i];
  963.             if (event.xunmap.window == imginfo->win){
  964.                 if (imginfo->channels == 1)
  965.                     LoadIcon(imginfo);
  966.                 XMapWindow(imginfo->dpy, imginfo->icon);
  967.             }
  968.             else if (event.xunmap.window == imginfo->icon)    {
  969.                 XMapWindow(imginfo->dpy, imginfo->frame);
  970. #ifndef    C_TUNER
  971.                 goto    ReSume0;
  972. #endif
  973.             }
  974.         }
  975.         while (XCheckMaskEvent(Dpy, StructureNotifyMask, &event));
  976.     break;
  977.  
  978.     case ConfigureNotify:    /* any window moving, changing size, ... */
  979.         /* we are only interested in window size change    */
  980.         ResizeWindow(img, &event);
  981.     break;
  982.  
  983.     case MotionNotify:
  984.     switch (clickon)    {
  985.         case ELALINFO:
  986.         SetSBarPos(slider, event.xbutton.x, event.xbutton.y, sb);
  987.         moved++;
  988.         break;
  989.         case CLIPINFO:
  990.         SetSBarPos(CSlider, event.xbutton.x, event.xbutton.y,sb);
  991.         moved++;
  992.         break;
  993.         case QUANINFO:
  994.         SetSBarPos(QSlider, event.xbutton.x, event.xbutton.y,sb);
  995.         moved++;
  996.         break;
  997.         case MOVESCROLLBAR:
  998.         SetScrollBar(img->parts, event.xbutton.x, event.xbutton.y, sb-1);
  999.         moved++;
  1000.         break;
  1001.         case HMARKPOS:
  1002.         DrawVMark(histinfo.his, event.xmotion.x, True);
  1003.         case IMAGEINFO:
  1004.         ParameterWin(imginfo, &histinfo, event.xbutton.x, event.xbutton.y,
  1005.                 y0, wp==histinfo.his->win);
  1006.         /* end of IMAGEINFO */
  1007.     }break;    /* end of clickon */
  1008.     default:    if (verbose)
  1009.         msg("%d Not a Panel Event\n", event.type);
  1010.     }
  1011.     }    /* end while */
  1012. }    /* End of Tuner */
  1013.  
  1014. void
  1015. SetImageEvent(img, event)
  1016. Image    *img;
  1017. XEvent    *event;
  1018. {
  1019.     img->event = event;
  1020.     img->color_dpy = cmn_hd.color_dpy;
  1021.     img->hist = nzalloc(HistoSize*3, sizeof(*(img->hist)), "hist");
  1022. }
  1023.  
  1024. void
  1025. Panel_Image(img, lkt)
  1026. Image    *img;
  1027. LKT    *lkt;
  1028. {
  1029.     SetSBarRPos(LSlider, img->linearlow, 1);
  1030.     SetSBarRPos(LSlider, img->linearup, 2);
  1031.     SetSBarRPos(ESlider, img->bgrd, 1);
  1032.     ChangeSliderScale(ESlider, img->scale, ESlider==slider);
  1033.     ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  1034. /*    ButtonState(maxButt of hButton) = img->setscale;    */
  1035. #ifdef    C_TUNER
  1036.     ButtonState(fButton) = img->fn;
  1037.     ChangePanelCmap(img);
  1038. #else
  1039.     SetShowFramePos(img, fButton, 0);
  1040. #endif
  1041.     DrawPanel();
  1042.     PanelMessage(FButton, img->name, 0, 0, 0);
  1043.     histinfo.histp = img->hist;    /* point to image histogram */
  1044. #ifndef    DIRECT
  1045.     if (histinfo.map || img->frames==1)
  1046. #endif
  1047.         new_curve(lkt, &histinfo, img->marray, img->curve, 0,
  1048.             img, img->width*img->height);
  1049.     HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  1050. }
  1051.  
  1052. void
  1053. Fresh_ImageScreen(img, rp, new_colors)
  1054. Image    *img;
  1055. byte    *rp;
  1056. int    *new_colors;
  1057. {
  1058. int    map_flag = 1;
  1059. register byte    *mtmp = rp;    /* here, rp is for interpolation only */
  1060. register int    i;
  1061.     img->linearlow = ReadSlider(LSlider, 1);
  1062.     img->linearup = ReadSlider(LSlider, 2);
  1063.     if (img->curve == ETABackGD)
  1064.         img->bgrd = ReadSlider(ESlider, 1);
  1065.     if (img->curve == ETAForeGD)
  1066.         img->fgrd = ReadSlider(ESlider, 1);
  1067. #ifdef    C_TUNER
  1068.     i = img->fn % 3;
  1069.     cer[i].lower = img->linearlow;
  1070.     cer[i].upper = img->linearup;
  1071.     cer[i].bgrd = img->bgrd;
  1072.     cer[i].fgrd = img->fgrd;
  1073. #endif
  1074.     if (PressButtonState(RstButt) || ButtonState(Interpolate))
  1075.     {
  1076.         ResetLKT(lkt, img);
  1077.         if (ButtonState(Interpolate)){
  1078.         sprintf(lbuf, "Interpolate %s[f%d]", img->name, img->fn);
  1079.         DispInfo(Epanel, 0, lbuf, white1);
  1080. #ifdef    C_TUNER
  1081.         if (img->channels > 1)
  1082.         {    memcpy(&cmn_hd, img, sizeof(cmn_hd));
  1083.             row *= img->channels;
  1084.             interpolation(img->data, img->scan_data,
  1085.             x_regions, y_regions, IM, &cmn_hd, &histinfo);
  1086.         } else
  1087. #endif
  1088.         interpolation(rp, mtmp=(VType*)img->image->data,
  1089.             x_regions, y_regions, IM, img, &histinfo);
  1090.         Find_min_max(img, histinfo.histp, mtmp, Yes, False);
  1091.         }
  1092.     }
  1093.     else new_curve(lkt, &histinfo, img->marray + (img->color_dpy ?
  1094.         img->fn%img->channels : (img->frames > 1 ? img->fn : 0)),
  1095.         img->curve, 0, img, img->width*img->height);
  1096.     if (img->color_dpy && img->fn == ButtonSync)    {
  1097.         cer[2] = cer[1] = cer[0];
  1098.         for (i=1; i<3; i++)
  1099.         memcpy(lkt+MaxColors*i, lkt, sizeof(*lkt)*MaxColors);
  1100.     }
  1101. #ifdef    DIRECT
  1102. #    ifdef    C_TUNER
  1103.     map_flag = img->dpy_depth < 24 &&
  1104.             ((image_information*)img)->visual_class < TrueColor;
  1105.     if(cer[0].intp || ButtonState(Interpolate) || !map_flag)    {
  1106.         eta_scan_map(img, ButtonState(Interpolate));
  1107.         mtmp = PrtCAST img->image->data;
  1108.         if (!map_flag)    {
  1109.         register LKT    *lktr=lkt, *lktg=lktr+MaxColors, *lktb=lktg+MaxColors;
  1110.           if (ImageByteOrder(img->dpy) != LSBFirst)
  1111.             for (i=img->image->bytes_per_line*img->height>>2; i--;) {
  1112.             mtmp++;
  1113.             *mtmp++ = lktb[*mtmp];
  1114.             *mtmp++ = lktg[*mtmp];
  1115.             *mtmp++ = lktr[*mtmp];
  1116.             }
  1117.           else for (i=img->image->bytes_per_line*img->height>>2; i--;){
  1118.             *mtmp++ = lktr[*mtmp];
  1119.             *mtmp++ = lktg[*mtmp];
  1120.             *mtmp++ = lktb[*mtmp];
  1121.             mtmp++;
  1122.             }
  1123.         }
  1124.         histogram(img->data, img->width*img->height, histinfo.histp, img);
  1125.         cer[0].intp = 0;
  1126.         Put_Image(img);
  1127.         ImageBackup(img);
  1128.     }
  1129. #    endif    C_TUNER
  1130.     if (map_flag)
  1131.         MapColor(img, mtmp, fsize, graylevel,
  1132.         MAX(VCTEntry, img->marray[img->fn].min));
  1133. #else
  1134.     if (quant && img->curve==ETALinear)    {
  1135.         *new_colors = CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  1136.         SetColormap(&Monitor[0], graylevel, new_colors, &newmap, quant);
  1137.     }
  1138.     MapColor(img, mtmp, fsize);
  1139.     Draw_ImageScrollBars(img);
  1140.     if (img->sub_img)
  1141.         DrawCrop(img, 0, 1);
  1142. #endif
  1143. }
  1144.  
  1145. Update_ImageData(img, lbuf)
  1146. Image    *img;
  1147. VType    *lbuf;
  1148. {
  1149. int    i;
  1150.     sprintf(lbuf, "Update %s[f%d]", img->name, img->fn);
  1151.     DispInfo(Epanel, 0, lbuf, white1);
  1152.     img->update = True;
  1153.     (*img->std_swif)(FI_DESC_ETA, img, lbuf, cer);
  1154. #ifdef    C_TUNER    /* update RGB image only */
  1155.     if (img->dpy_channels > 1)    {
  1156.     register int    j, ch, *lktp;
  1157.     byte    *pp[3], *dp[3];
  1158.     int    my,
  1159.         s_w = img->sub_img ? img->sub_img_w : img->width,
  1160.         s_h = img->sub_img ? img->sub_img_h : img->height,
  1161.         X0 = img->sub_img ? img->sub_img_x : 0,
  1162.         Y0 = img->sub_img ? img->sub_img_y : 0,
  1163.         icon_factor = get_iconsize(img, 0);
  1164.         for (i=0; i<s_h; i++)    {
  1165.         my = Y0 + s_h - i - 1;
  1166.         pp[0] = ORIG_RLE_ROW(img, my);
  1167.         pp[1] = pp[0] + img->width;
  1168.         pp[2] = pp[1] + img->width;
  1169.         dp[0] = SAVED_RLE_ROW(img, my);
  1170.         dp[1] = dp[0] + img->width;
  1171.         dp[2] = dp[1] + img->width;
  1172.         for (ch=0; ch<img->dpy_channels; ch++)    {
  1173.         register int    min = img->marray[ch].min;
  1174.             lktp = lkt + ch*MaxColors;
  1175.             for (j=X0; j<s_w+X0; j++)
  1176.             pp[ch][j] = lktp[pp[ch][j] - min];
  1177.         }
  1178.         MapRGB(0, 0, &img, pp, dp, my, img->width,
  1179.             my, icon_factor);
  1180.         }
  1181.         histogram(img->data, img->width*img->height, histinfo.histp, img);
  1182.         Put_Image(img);    ImageBackup(img);
  1183.     }
  1184.     else
  1185. #endif
  1186.     if (ButtonState(Interpolate))
  1187.         interpolation(img->cnvt, img->cnvt, x_regions, y_regions,
  1188.         IM, img, &histinfo);
  1189.     else    {
  1190.     register byte    *bp = img->cnvt;
  1191.     register int    min = img->mmm.min;
  1192.         if (img->sub_img){
  1193.         register int    j;
  1194.         bp += img->sub_img_y * img->width + img->sub_img_x;
  1195.         for (i=0; i<img->sub_img_h; i++){
  1196.             for (j=0; j<img->sub_img_w; j++)
  1197.             bp[j] = lkt[bp[j] - min];
  1198.             bp += img->width;
  1199.         }
  1200.         }
  1201.         else for (i=fsize; i--;)
  1202.             bp[i] = lkt[bp[i] - min];
  1203.     }
  1204.     if (verbose)    sleep(2);
  1205.     ButtonState(EButton) = ETALinear;
  1206.     ButtonState(DButton) = RESETSTATE;
  1207.     DrawButton(DButton);
  1208. }
  1209.  
  1210. void
  1211. PasteImage(img, y0)
  1212. Image    *img;
  1213. int    *y0;
  1214. {
  1215.     TopWindow(img, img->sub_img=0);
  1216.     /* handle exposure generated from TopWindow 1st.    */
  1217.     do    {
  1218.         Exposure_handler(img->event, img);
  1219.         XFlush(img->dpy);
  1220.     } while (ImageEvent(img, ExposureMask));
  1221.     memcpy(I_ED.copy, img, sizeof(Image));
  1222.     XDefineCursor(img->dpy, img->win, 0);
  1223.     I_ED.copy->sub_img_w = I_ED.w;
  1224.     I_ED.copy->sub_img_h = I_ED.h;
  1225.     while (!ImageEvent(img, ButtonReleaseMask))
  1226.     if (ImageEvent(img, PointerMotionMask))    {
  1227.     register int    yo;
  1228.         if (I_ED.copy->sub_img)
  1229.             DrawCrop(I_ED.copy, 0, 1);
  1230.         I_ED.dstx = I_ED.copy->sub_img_x = img->event->xbutton.x;
  1231.         I_ED.dsty = I_ED.copy->sub_img_y = img->event->xbutton.y;
  1232.         yo = SetParameterWin(img, img->event, img->font_h, 0);
  1233.         if (yo != *y0) {
  1234.             ClearParameterWin(img, *y0=yo);
  1235.             while (ImageEvent(img, ExposureMask))
  1236.                 Exposure_handler(img->event, img);
  1237.         }
  1238.         ParameterWin(img, &histinfo, I_ED.dstx, I_ED.dsty, yo, 0);
  1239.         I_ED.copy->sub_img = DrawCrop(I_ED.copy, 0, 1);
  1240.     }
  1241.     {
  1242.     register int    i, Isize = img->width * img->height,
  1243.             w = MIN(I_ED.w, img->width - I_ED.dstx),
  1244.             h = MIN(I_ED.h, img->height - I_ED.dsty);
  1245.     byte* cpbuf = (img->data + (img->color_dpy || img->frames<2
  1246.             ? 0 : img->fn * Isize) ),
  1247.         *src_area = (I_ED.src->channels < img->channels) ? (byte*)
  1248.             map_1_to_3(I_ED.copyarea, NULL, I_ED.src->in_cmap,
  1249.                 I_ED.w, I_ED.h) : (byte*)I_ED.copyarea;
  1250.         if (img && w>0 && h>0 && I_ED.dstx>=0 && I_ED.dsty>=0)    {
  1251.         {
  1252.         register byte    *srcp = src_area, *cp = cpbuf + I_ED.dstx +
  1253.                 I_ED.dsty*img->width*img->channels;
  1254.         register int    factors=I_ED.src->channels/img->channels;
  1255.         if (factors)    factors--;    /* color quant will be here */
  1256.         i = MAX(MaxColors, I_ED.src->cmaplen);    /* tricky of buildmap */
  1257.             if (I_ED.src != img && img->dpy_channels == 1 &&
  1258.             I_ED.src->dpy_channels == img->dpy_channels &&
  1259.                 I_ED.src->color_dpy) {
  1260.             cmap_t    transf[MaxColors];
  1261.             register cmap_t    *cr=I_ED.src->in_cmap[0], *cg=cr+i, *cb=cg+i;
  1262.             for (i=I_ED.src->cmaplen; i--;)
  1263.                 transf[i] = CloseColor_in_Map(img->in_cmap,
  1264.                     img->cmaplen, cr[i], cg[i], cb[i], 384);
  1265.             for (i=I_ED.w * I_ED.h; i--;)
  1266.                 srcp[i] = transf[srcp[i]];
  1267.             }
  1268.             for (i=h; i--; srcp += I_ED.w*factors)    {
  1269.             register int    chan = img->channels;
  1270.                 while (chan--)
  1271.                 memcpy(cp, srcp, w),
  1272.                 srcp += I_ED.w,
  1273.                 cp += img->width;
  1274.             }
  1275.         }
  1276.         if (src_area != (byte*)I_ED.copyarea)
  1277.             free(src_area);
  1278.         I_ED.dst = img;
  1279.         img->sub_img_x = I_ED.dstx;
  1280.         img->sub_img_y = I_ED.dsty;
  1281.         img->sub_img_w = w;
  1282.         img->sub_img_h = h;
  1283.         img->update = True;
  1284. #    ifndef    C_TUNER
  1285.         XClearArea(img->dpy, img->win,
  1286.             I_ED.dstx, I_ED.dsty, I_ED.w, I_ED.h, 1);
  1287. #    endif
  1288. #    ifndef    DIRECT
  1289.         Find_min_max(img, histinfo.histp, cpbuf, Yes, True);
  1290. #    endif
  1291. #    ifndef    DIRECT
  1292.         ResetORange(img);
  1293.         ResetLKT(lkt, img);
  1294.         MapColor(img, cpbuf, Isize);
  1295. #    elif    C_TUNER
  1296.         {
  1297.         byte    *scan_line[3], *dp[3];
  1298.         register int    l, my, icon_factor=get_iconsize(img, 0);
  1299.             for (l=0; l<h; l++)    {
  1300.             my = I_ED.dsty + l - 1;
  1301.             scan_line[0] = ORIG_RLE_ROW(img, my);
  1302.             dp[0] = SAVED_RLE_ROW(img, my);
  1303.             for (i=1; i<img->channels; i++)
  1304.                 scan_line[i] = scan_line[i-1] + I_ED.dst->width,
  1305.                 dp[i] = dp[i-1] + I_ED.dst->width;
  1306.             MapRGB(0, NULL, &img, scan_line, dp,
  1307.                 my, I_ED.dst->width, my, icon_factor);
  1308.             }
  1309.         }
  1310.         PlaceArea(img, I_ED.dstx, I_ED.dsty, I_ED.w, I_ED.h);
  1311. #    endif
  1312.         }    /* end if */    else    DrawCrop(I_ED.copy, 0, 1);
  1313.     }    /* end section */
  1314. Find_min_max(img, histinfo.histp=img->hist, img->data, Yes, True);
  1315. }
  1316.  
  1317. void
  1318. PaintImage(img, y0, s, r, g, b)
  1319. Image    *img;
  1320. int    *y0;
  1321. {
  1322. int    wh, d = img->sub_img_w = img->sub_img_h = (s<<1) + 1,
  1323.     gs = AdoptColor(img, r, g, b, precision);
  1324.  
  1325.     while (1) {
  1326.     wh = WaitButtonPress_n_InfoImage(img, &histinfo, y0,
  1327.         XCreateFontCursor(img->dpy, XC_crosshair));
  1328.     RemoveImageEvent(img, ButtonAction)    XBell(img->dpy, 0);
  1329.     if (wh == Button3)    break;
  1330.     if (wh == Button2)    {
  1331.         gs = PickUpColor(img, &r, &g, &b);
  1332.         continue;
  1333.     }
  1334.     XDefineCursor(img->dpy, img->win, XCreateFontCursor(img->dpy, XC_pencil));
  1335.  
  1336.     img->update = True;
  1337.     while (!ImageEvent(img, ButtonReleaseMask))
  1338.         if (ImageEvent(img, PointerMotionMask))
  1339.         PaintArea(img, img->cnvt, img->event->xbutton.x,
  1340.             img->event->xbutton.y, r, g, b, gs, s);
  1341.     }    /* end while (1) */
  1342. }
  1343.  
  1344. CopyOrCutSubImage(img, ed_cut)
  1345. Image    *img;
  1346. {
  1347.     I_ED.x0 = img->sub_img_x;
  1348.     I_ED.y0 = img->sub_img_y;
  1349.     I_ED.w = img->sub_img_w;
  1350.     I_ED.h = img->sub_img_h;
  1351.     if (I_ED.copyarea)
  1352.         free(I_ED.copyarea);
  1353.     I_ED.copyarea = nzalloc(I_ED.w * I_ED.h, img->channels, "I_ED.copy");
  1354.     {
  1355.     register byte*    cp = I_ED.copyarea,
  1356.         *srcp = img->cnvt + img->channels*img->width*I_ED.y0 + I_ED.x0;
  1357.     register int    i;
  1358.         for (i=I_ED.h*img->channels; i--;) {
  1359.             memcpy(cp, srcp, I_ED.w);
  1360.             cp += I_ED.w;
  1361.             srcp += img->width;
  1362.         }
  1363.         if (I_ED.cut = ed_cut)    {
  1364.         int    r, g, b=BackGD;
  1365.             if (img->in_cmap)    {
  1366.                 r = img->in_cmap[0][b];
  1367.                 g = img->in_cmap[1][b];
  1368.                 b = img->in_cmap[2][b];
  1369.             } else    r = g = b;
  1370.         PaintArea(img, img->data, I_ED.x0, I_ED.y0, r, g, b, BackGD, 0);
  1371.         }
  1372.         I_ED.fill = True;
  1373.         I_ED.src = img;
  1374.     }
  1375. }
  1376.  
  1377. PrepareToEdit(imgp, num_imgs, msg, lbuf, size, event)
  1378. Image**    imgp;
  1379. XEvent*    event;
  1380. char*    msg, *lbuf;
  1381. {
  1382.     sprintf(lbuf, "R=%d, G=%d, B=%d", fnt_r, fnt_g, fnt_b);
  1383.     Get_Note_Input(lbuf, size, 8, "R, G, B ", Green, 0);
  1384.     sscanf(lbuf, "%d %d %d", &fnt_r, &fnt_g, &fnt_b);
  1385.     DisplayMessage(NoteWin, msg, 4, 0);
  1386.     XMaskEvent(Dpy, ButtonPressMask, event);
  1387. return    WhichImage(event->xany.window, imgp, num_imgs);
  1388. }
  1389.  
  1390. PaintArea(img, rp, x0, y0, r, g, b, gs, err)
  1391. Image    *img;
  1392. byte    *rp;
  1393. {
  1394. byte    *scan[3];
  1395. register int    x = img->sub_img_x = x0 - err,
  1396.         y = img->sub_img_y = y0 - err,
  1397.         dy=img->sub_img_h, dx=img->sub_img_w, rt_x, rt_y;
  1398.         err <<= 1;
  1399.     if (x >= 0 && x < img->width-err && y >= 0 && y < img->height-err)
  1400.     for (rt_y=y+dy; rt_y-- > y;)    {
  1401.     byte    *p[3];
  1402.     err = rt_y*img->width*img->channels + x;
  1403.     p[0] = rp + err;
  1404.     p[1] = p[0] + img->width;
  1405.     p[2] = p[1] + img->width;
  1406.         for (rt_x=dx; rt_x--;) {
  1407.         if (img->channels == 1)
  1408.             p[0][rt_x] = gs;
  1409.         else    {
  1410.             p[0][rt_x] = r;
  1411.             p[1][rt_x] = g;
  1412.             p[2][rt_x] = b;
  1413.         }
  1414.         }
  1415. #    ifdef    C_TUNER
  1416.         scan[0] = img->scan_data + err;
  1417.         scan[1] = scan[0] + img->width;
  1418.         scan[2] = scan[1] + img->width;
  1419.         Map_Scanline(img, p, scan, x, rt_y, dx, get_iconsize(img, 0));
  1420. #    endif
  1421.     }
  1422. #    ifndef    C_TUNER
  1423.     img->sub_img++;
  1424.     MapColor(img, rp, img->width * img->height);
  1425. #    endif
  1426.     PlaceArea(img, x, y, dx, dy);
  1427. img->sub_img = 0;
  1428. }
  1429.  
  1430. PlaceArea(img, x, y, dx, dy)
  1431. register Image    *img;
  1432. register int    x, y, dx, dy;
  1433. {
  1434. register int    x0=x, y0=y;
  1435. #ifndef    SCROLLBAR_on_CANVAS
  1436.     x -= img->x0,    y -= img->y0;
  1437. #endif
  1438.     XPutImage(img->dpy, img->win, img->gc, img->image,
  1439.             x0, y0, x, y, dx, dy);
  1440. #    ifdef    C_TUNER
  1441.     if (img->refresh_pixmap)
  1442.         XCopyArea(img->dpy, img->win, img->refresh_pixmap,
  1443.             img->gc, x, y, dx, dy, x0, y0);
  1444. #    endif
  1445. }
  1446.  
  1447.